// Constants
var imageWidth = 55;

// Initialization
init();

function init() {
  loadDiscovered();
  configureWorkspace();
  configureFilter();
  configureBin();
  configureMenuBar();
}

function configureMenuBar() {
  $( '#clean' ).click( function() {
    removeElement( $( '#maincol > .elem' ) );
  } );
  $( '#rearrange' ).click( function() {
    reArrange();
  } );
  $( '#help' ).click( function() {
		$( '#helpDiv' ).dialog({
			height: 500,
			width: 500,
			title: 'Help',
			resizable: false,
			modal: true
		});
  } );
}

function configureWorkspace() {
  $( '#maincol' ).disableSelection();
  $( '#maincol' ).dblclick( function( event ) {
    if ( $( event.target ).attr( 'id' ) == 'maincol' ) {
      addBasic( event );
    }
  } );
}

function configureFilter() {
  $( '#filterBox' ).keyup( function() {
    doFilter();
  } );
}

function configureBin() {
  $( "#bin" ).droppable( {
    drop : handleDropBin,
    over : function( event, ui ) {
      ui.draggable.css( 'opacity', '0.4' );
    },
    out : function( event, ui ) {
      ui.draggable.css( 'opacity', '1' );
    }
  } );
}

function handleDropBin( event, ui ) {
  var draggable = ui.draggable;
  removeElement( draggable );
}

function loadDiscovered() {
  $( '#loader' ).show();
  $.getJSON( "/api/combination/discovered", function( json ) {
    addElementsToPalette( json );
    $( '#user' ).text( json.user );
    $( '#discovered' ).text( json.elementList.length );
    $( '#total' ).text( json.total );
    $( '#userInfo' ).show();
    $( '#loader' ).hide( );
    $( '#loader' ).hide();
  } );
}

function addBasic( event ) {
  $.getJSON( "/api/combination/basic", function( json ) {
    var left = event.pageX - $( '#maincol' ).offset().left;
    var top = event.pageY - $( '#maincol' ).offset().top + $( '#maincol' ).scrollTop();
    addElementsToWorkspace( json, left, top );
  } );
}

function addElementsToPalette( json ) {
  var elements = json.elementList;
  $.each( elements, function( index, value ) {
    var element = createElement( value.id, value.name, value.imagePath, value.finalElement );
    addElementToPalette( element );
  } );
}

function addElementsToWorkspace( json, givenLeft, givenTop ) {
  var elements = json.elementList;
  var position = getPosition( givenLeft, givenTop );
  $.each( elements, function( index, value ) {
    var element = createElement( value.id, value.name, value.imagePath, value.finalElement );
    addElementToWorkspace( element, position.left, position.top );
    position = getPosition();
  } );
}

function getPosition( left, top ) {
  var elems = $( '#maincol > .elem:last' );
  var newLeft = left;
  var newTop = top;
  if ( left == null ) {
    newLeft = elems.position().left + imageWidth + 5;
  }
  if ( top == null ) {
    newTop = elems.position().top + $( '#maincol' ).scrollTop();
  }
  var maxWidth = $( '#maincol' ).innerWidth();
  var maxHeight = $( '#maincol' ).innerHeight();
  if ( maxWidth - 5 - newLeft <= imageWidth ) {
    newLeft = 0;
    newTop = newTop + elems.outerHeight() + 5 + $( '#maincol' ).scrollTop();
  }
  if ( maxHeight - 5 - newTop <= elems.outerHeight() ) {
    newLeft = 0;
    newTop = 0;
  }
  return {
    left : newLeft,
    top : newTop
  };
}

function createElement( id, name, imagePath, isFinal ) {
  var elemTextClass = "elemText" + ( isFinal == true ? 'Final' : '' );
  var imgTag = $( "<div id='" + id + "' class='elem'><img final='" + isFinal + "' class='elemImg' id='" + id + "' title='" 
		  + name + "' alt='" + name + "' src='" + imagePath + "'/>" + "<br/><label class='" + elemTextClass + "'>" 
		  + name + "</label>" + "</div>" );
  imgTag.dblclick( function() {
    var elems = $( '#maincol > .elem:last' );
    if ( elems.length > 0 ) {
      var position = getPosition();
      addElementToWorkspace( imgTag, position.left, position.top );
    } else {
      addElementToWorkspace( imgTag );
    }
  } );
  return imgTag;
}

function addElementToPalette( element ) {
  element.fadeIn();
  $( '#palette' ).append( element );
}

function handleDropEvent( event, ui ) {
  var draggable = ui.draggable;
  combine( draggable, $( this ) );
}

function combine( elem1, elem2 ) {
  if ( $( elem1.children()[ 0 ] ).attr( 'final' ) != 'true' && $( elem2.children()[ 0 ] ).attr( 'final' ) != 'true' ) {
    $.getJSON( "/api/combination/combine?", {
      element1 : elem1.attr( 'id' ),
      element2 : elem2.attr( 'id' )
    }, function( json ) {
      var elements = json.elementList;
      var position = getPosition( elem1.position().left, elem1.position().top );
      $.each( elements, function( index, value ) {
        var element = createElement( value.id, value.name, value.imagePath, value.finalElement );
        if ( $( "#" + value.id ).length == 0 ) {
          addElementToPalette( element );
          var total = $( '#palette > .elem > .elemImg' ).length;
          $( '#discovered' ).text( total );
        }
        addElementToWorkspace( element, position.left, position.top );
        position = getPosition();
      } );
      if ( elements.length != 0 ) {
        removeElement( elem1 );
        removeElement( elem2 );
      }
    } );
  } 
}

function addElementToWorkspace( element, left, top ) {
  var addedElement = element.clone();
  addedElement.dblclick( function() {
    removeElement( $( this ) );
  } );
  addedElement.draggable( {
    containment : '#maincol',
    scroll : false
  } );
  addedElement.droppable( {
    drop : handleDropEvent
  } );
  addedElement.css( 'position', 'absolute' );
  addedElement.css( 'top', top );
  addedElement.css( 'left', left );
  addedElement.css( 'display', 'none' );
  addedElement.css( 'opacity', 1 );
  $( '#maincol' ).append( addedElement );
  addedElement.fadeIn( 'slow' );
  addedElement.bind( 
      "contextmenu", 
      function ( event ) {
        removeElement( $( this ) );
        return false;
      }
  );
}

function removeElement( element ) {
  element.fadeOut( 'slow', function() {
    element.remove()
  } );
}

function doFilter() {
  var currentValue = $( '#filterBox' ).val();
  var elems = $( '#palette > .elem > .elemImg' );
  for ( i = 0; i < elems.length; i++ ) {
    var elem = elems[ i ];
    if ( currentValue == "" || currentValue == null || ( elem.alt.toLowerCase().toLowerCase().indexOf( currentValue.toLowerCase() ) >= 0 ) ) {
      $( elem ).parent().show();
    } else {
      $( elem ).parent().hide();
    }
  }
}

function reArrange() {
  var elements = new Object();
  var elementList = new Array();
  $.each( $( '#maincol > .elem .elemImg' ), function( index, value ) {
    var element = $( value );
    var newElement = new Object();
    newElement.id = element.attr( 'id' );
    newElement.name = element.attr( 'alt' );
    newElement.imagePath = element.attr( 'src' );
    newElement.finalElement = element.attr( 'final' ) == 'true' ? true : false;
    elementList[ index ] = newElement;
  } );
  $( '#maincol > .elem' ).remove();
  elements.elementList = elementList;
  addElementsToWorkspace( elements, 0, 0 );
}